package com.hy.controller;

import com.hy.common.pojo.Products;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created With IntelliJ IDEA.
 * Descriptions:
 * author: Mr.Du
 * Date: 2022/10/19
 * Time: 19:59
 */
@RestController
@RequestMapping("/page")
public class PageController {
    
    @Resource
    private RestTemplate restTemplate;
    
    // 服务注册中心的客户端对象
    @Resource
    private DiscoveryClient discoveryClient;
    /**
    @GetMapping("/getData/{id}")
    public Products findDataByIdUseRestTemplate(@PathVariable Integer id){
        Products products =
                restTemplate.getForObject("http://localhost:9000/product/query/"+id, Products.class);
        System.out.println("从hy-service-product获得product对象:"+products);
        return products;
    }
    */
    
    @GetMapping("/getData/{id}")
    public Products findDataById(@PathVariable Integer id){
        // 1.获得Eureka中注册的hy-service-product实例集合
        //List<ServiceInstance> instances = discoveryClient.getInstances("hy-service-product");
    
        //2.获得实例集合中的第一个
        //ServiceInstance instance = instances.get(0);
        //3.根据实例信息拼接IP地址
        //String host = instance.getHost();
        //int port = instance.getPort();
        String url = "http://hy-service-product/product/query/"+id;
        //4.调用
        Products products = restTemplate.getForObject(url, Products.class);
        System.out.println("从hy-service-product获得product对象:"+products);
        return products;
    }
    
    @GetMapping("/loadProductServicePort")
    public String getProductServicePort(){
        // 负载均衡直接调用，不用写下面这些注释掉的代码
        //List<ServiceInstance> instances = discoveryClient.getInstances("hy-service-product");
        //ServiceInstance serviceInstance = instances.get(0);
        //String host = serviceInstance.getHost();
        //int port = serviceInstance.getPort();
        String url = "http://hy-service-product/service/port";
        String result = restTemplate.getForObject(url, String.class);
        return result;
    }
    
    /**
     * 模拟服务超时，熔断处理
     * 针对熔断处理，Hystrix默认维护一个线程池，默认大小为10
     * @return
     */
    @HystrixCommand(
            threadPoolKey = "getProductServicePort2"  // 默认所有请求共同维护一个线程池，所以实际开发每个方法维护一个线程池
            // 每一个属性对应的都是一个HystrixProperty
            //threadPoolProperties = {
            //        @HystrixProperty(name = "coreSize",value = "1"),   // 并发线程数
            //        @HystrixProperty(name = "maxQueueSize",value = "20"),  // 默认线程队列值是-1，默认不开启
            //        //设置队列拒绝数，默认是5，当请求数超过15时，超过的请求就不算数
            //        @HystrixProperty(name = "queueSizeRejectionThreshold",value = "15"),
            //        配置在yml文件中
            //},
            // 超时时间设置
            //commandProperties = {
            //        // 设置请求超时时间，一旦请求超过此时间设置，那么按超时处理，默认超时时间是1s
            //        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
            //}
    )
    @GetMapping("/loadProductServicePort2")
    public Object getProductServicePort2(){
        String url = "http://hy-service-product/service/port";
        String result = restTemplate.getForObject(url, String.class);
        return result;
    }
    
    /**
     *  模拟超时，降级处理
     * @return
     */
    @HystrixCommand(
            // 只要是在@HystrixCommand中定义了threadPoolKey，就意味着开启了舱壁模式，该方法就会自己维护一个线程池
            threadPoolKey = "getProductServicePort3",
            //threadPoolProperties = {
            //        @HystrixProperty(name="coreSize",value = "1"),
            //        @HystrixProperty(name = "maxQueueSize",value = "20"),
            //        //设置队列拒绝数，默认是5，当请求数超过15时，超过的请求就不算数
            //        @HystrixProperty(name = "queueSizeRejectionThreshold",value = "15"),
            //        配置在yml文件中
            //},
            //commandProperties = {
            //        配置在yml文件中
            //},
            fallbackMethod = "myFallBack"  // 回退方法
    )
    @GetMapping("/loadProductServicePort3")
    public Object getProductServicePort3(){
        String url = "http://hy-service-product/service/port";
        String result = restTemplate.getForObject(url, String.class);
        return result;
    }
    
    /**
     * 定义回退方法，当请求触发熔断后执行
     * @return
     */
    public Object myFallBack(){
        return "-1";
    }
    
}
